﻿namespace FiftyOne.Foundation.Mobile.Detection.Wurfl
{
    using FiftyOne.Foundation.Mobile.Detection;
    using FiftyOne.Foundation.Mobile.Detection.Wurfl.Matchers;
    using System;
    using System.Drawing.Imaging;
    using System.Runtime.InteropServices;

    public class DeviceInfo
    {
        private Collection _deviceCapabilities;
        private string _deviceId;
        private Provider _devices;
        private DeviceInfo _fallbackDevice;
        private bool _isActualDeviceRoot;
        private string _userAgent;

        private DeviceInfo()
        {
        }

        internal DeviceInfo(DeviceInfo source, string deviceId) : this(source._devices, deviceId, source._userAgent, source)
        {
        }

        internal DeviceInfo(Provider devices, string deviceId)
        {
            this.Init(devices, deviceId);
        }

        internal DeviceInfo(Provider devices, string deviceId, string userAgent)
        {
            this.Init(devices, deviceId, userAgent);
        }

        internal DeviceInfo(Provider devices, string deviceId, string userAgent, DeviceInfo fallbackDevice)
        {
            if (fallbackDevice == null)
            {
                throw new ArgumentNullException("fallbackDevice");
            }
            this.Init(devices, deviceId, userAgent);
            this._fallbackDevice = fallbackDevice;
        }

        public string GetCapability(string capabilityName)
        {
            string capability = this._deviceCapabilities.Get(capabilityName);
            if ((capability == null) && (this._fallbackDevice != null))
            {
                capability = this._fallbackDevice.GetCapability(capabilityName);
                if (capability != null)
                {
                    this._deviceCapabilities.Set(capabilityName, capability);
                }
            }
            return capability;
        }

        public bool GetCapability(string capabilityName, out bool capabilityValue)
        {
            return bool.TryParse(this.GetCapability(capabilityName), out capabilityValue);
        }

        public bool GetCapability(string capabilityName, out int capabilityValue)
        {
            return int.TryParse(this.GetCapability(capabilityName), out capabilityValue);
        }

        public bool GetCapability(string capabilityName, out long capabilityValue)
        {
            return long.TryParse(this.GetCapability(capabilityName), out capabilityValue);
        }

        internal string GetCapabilityNoFallback(string capabilityName)
        {
            return this._deviceCapabilities.Get(capabilityName);
        }

        private void Init(Provider devices, string deviceId)
        {
            if (string.IsNullOrEmpty(deviceId))
            {
                throw new ArgumentNullException("deviceId");
            }
            if (devices == null)
            {
                throw new ArgumentNullException("devices");
            }
            this._devices = devices;
            this._deviceId = deviceId;
            this._deviceCapabilities = new Collection();
        }

        private void Init(Provider devices, string deviceId, string userAgent)
        {
            if (userAgent == null)
            {
                throw new ArgumentNullException("userAgent");
            }
            this._userAgent = UserAgentParser.Parse(userAgent);
            this.Init(devices, deviceId);
        }

        internal void SetUserAgent(string value)
        {
            if (this._userAgent != value)
            {
                this._userAgent = value;
                this._devices.Set(this);
            }
        }

        public bool SupportsImageFormat(ImageFormat format)
        {
            string capabilityName = null;
            if (format.Guid == ImageFormat.Gif.Guid)
            {
                capabilityName = "gif";
            }
            else if (format.Guid == ImageFormat.Png.Guid)
            {
                capabilityName = "png";
            }
            else if (format.Guid == ImageFormat.Jpeg.Guid)
            {
                capabilityName = "gif";
            }
            return ((capabilityName != null) && bool.TrueString.Equals(this.GetCapability(capabilityName)));
        }

        internal Collection Capabilities
        {
            get
            {
                return this._deviceCapabilities;
            }
        }

        internal string DeviceId
        {
            get
            {
                return this._deviceId;
            }
        }

        internal DeviceInfo FallbackDevice
        {
            get
            {
                return this._fallbackDevice;
            }
            set
            {
                this._fallbackDevice = value;
            }
        }

        internal bool IsActualDeviceRoot
        {
            get
            {
                return this._isActualDeviceRoot;
            }
            set
            {
                this._isActualDeviceRoot = value;
            }
        }

        internal bool IsMobileDevice
        {
            get
            {
                return bool.TrueString.Equals(this.GetCapability("is_wireless_device"), StringComparison.InvariantCultureIgnoreCase);
            }
        }

        internal string UserAgent
        {
            get
            {
                return this._userAgent;
            }
        }
    }
}

